package modelo.bd.dao;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import modelo.bd.ConexionPool;
import modelo.bd.excepcion.DAOException;
import modelo.dominio.Usuario;
import modelo.servicio.Areas;
import modelo.servicio.Historicos;

public class UsuarioDAO { //extends AbstractDAO<Usuario> {

    private String query;

    public void add(Usuario entity) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            /*
             * PROCEDURE [dbo].[SSMA_ALTER_USUARIO_P] --ARGUMENTOS POR DEFECTO
             * @ACCION VARCHAR(1), @USUARIO VARCHAR(25), --ARGUMENTOS DE LA
             * TABLA @LOGIN VARCHAR(25), @NOMBRE VARCHAR(150), @APELLIDOS
             * VARCHAR(150), @PERFIL VARCHAR(1), @PUESTO VARCHAR(50), @AREA INT,
             * @CONTRASENA VARCHAR(45), @ESTADO VARCHAR(2)
             */
            query = "EXEC SSMA_ALTER_USUARIO_P ";
            query += "'I'";
            query += ", '" + entity.getHistorico().getUsuarioCrea() + "'";
            query += ", '" + entity.getLogin() + "'";
            query += ", '" + entity.getNombre().replace("'", "''") + "'";
            query += ", '" + entity.getApellidos().replace("'", "''") + "'";
            query += ", 'U'";
            query += ", '" + entity.getPuesto().replace("'", "''") + "'";
            query += ", " + entity.getArea().getIdArea();
            query += ", '" + entity.getContrasena() + "'";
            query += ", 'CR'";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("1 USDA-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("2 USDA-SQL " + ex.getMessage());
            }
        }
    }

    public void deleteWhere(String condition) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            query = "UPDATE SSMA_HISTORICO_T SET ESTADO = 'IN' WHERE ID_HISTORICO IN ";
            query += " (SELECT ID_HISTORICO FROM SSMA_USUARIOS_T WHERE " + condition + ")";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("1 USDD-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("2 USDD-SQL " + ex.getMessage());
            }
        }
    }

    public void update(Usuario entity) throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        try {
            /*
             * CREATE PROCEDURE [dbo].[SSMA_ALTER_USUARIO_P] --ARGUMENTOS POR
             * DEFECTO @ACCION VARCHAR(1), @USUARIO VARCHAR(25), --ARGUMENTOS DE
             * LA TABLA @LOGIN VARCHAR(25), @NOMBRE VARCHAR(150), @APELLIDOS
             * VARCHAR(150), @PERFIL VARCHAR(1), @PUESTO VARCHAR(50), @AREA INT,
             * @CONTRASENA VARCHAR(45), @ESTADO VARCHAR(2)
             */
            query = "EXEC SSMA_ALTER_USUARIO_P ";
            query += "'U'";
            query += ", '" + entity.getHistorico().getUsuarioCrea() + "'";
            query += ", '" + entity.getLogin().replace("'", "''") + "'";
            query += ", '" + entity.getNombre().replace("'", "''") + "'";
            query += ", '" + entity.getApellidos().replace("'", "''") + "'";
            query += ", '" + entity.getPerfil() + "'";
            query += ", '" + entity.getPuesto().replace("'", "''") + "'";
            query += ", " + entity.getArea().getIdArea();
            query += ", '" + entity.getContrasena() + "'";
            query += ", 'ED'";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            sentencia.executeUpdate();
        } catch (SQLException ex) {
            throw new DAOException("1 USDU-SQL " + ex.getMessage());
        } finally {
            try {
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("2 USDU-SQL " + ex.getMessage());
            }
        }
    }

    protected List<Usuario> select() throws DAOException {
        Connection conexion = null;
        PreparedStatement sentencia = null;
        ResultSet resultado = null;
        List<Usuario> resultados = null;
        try {
            conexion = ConexionPool.getInstancia().getConexion();
            boolean si = conexion.getAutoCommit();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            resultados = new ArrayList<Usuario>();
            while (resultado.next()) {
                Usuario us = new Usuario();
                us.setLogin(resultado.getString("LOGIN"));
                us.setNombre(resultado.getString("NOMBRE"));
                us.setApellidos(resultado.getString("APELLIDOS"));
                us.setArea(Areas.instancia().obtenerPorId(resultado.getInt("ID_AREA")));
                us.setPerfil(resultado.getString("PERFIL"));
                us.setPuesto(resultado.getString("PUESTO"));
                us.setContrasena(resultado.getString("CONTRASENA"));
                us.setHistorico(Historicos.instancia().obtenerPorId(resultado.getInt("ID_HISTORICO")));
                resultados.add(us);
            }
        } catch (SQLException ex) {
            throw new DAOException("1 USDS-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("2 USDS-SQL " + ex.getMessage());
            }
        }
        return resultados;
    }

    public List<Usuario> selectAll() throws DAOException {
        query = "SELECT * FROM SSMA_USUARIOS_T WHERE ID_HISTORICO NOT IN (SELECT ID_HISTORICO FROM SSMA_HISTORICO_T WHERE ESTADO = 'IN')";
        return select();
    }

    public List<Usuario> selectWhere(String condition) throws DAOException {
        query = "SELECT * "
                + "FROM SSMA_USUARIOS_T "
                + "WHERE " + condition 
                + " AND ID_HISTORICO NOT IN (SELECT ID_HISTORICO "
                + "                          FROM SSMA_HISTORICO_T "
                + "                          WHERE ESTADO = 'IN')";
        return select();
    }

    public List<Usuario> selectPag(int desde, int hasta, Integer area) throws DAOException {
        query = "SELECT * FROM ("
                + " SELECT ROW_NUMBER()"
                + " OVER(ORDER BY LOGIN) AS LINEA,"
                + " SUT.*"
                + " FROM SSMA_USUARIOS_T SUT"
                + " WHERE ID_AREA = " + area
                + " AND ID_HISTORICO NOT IN (SELECT ID_HISTORICO FROM SSMA_HISTORICO_T WHERE ESTADO = 'IN')"
                + ") A"
                + " WHERE A.LINEA BETWEEN " + desde
                + " AND " + hasta;
        return select();
    }

    public int selectCount(Integer area) throws DAOException {
        PreparedStatement sentencia = null;
        Connection conexion = null;
        ResultSet resultado = null;
        int contador = 0;
        try {
            query = "SELECT COUNT(1) AS CUENTA "
                    + "FROM SSMA_USUARIOS_T "
                    + "WHERE ID_AREA = " + area 
                    + " AND ID_HISTORICO NOT IN (SELECT ID_HISTORICO "
                    + "                          FROM SSMA_HISTORICO_T "
                    + "                          WHERE ESTADO = 'IN')";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareStatement(query);
            resultado = sentencia.executeQuery();
            if (resultado.next()) {
                contador = resultado.getInt("CUENTA");
            } else {
                contador = 0;
            }
        } catch (SQLException ex) {
            throw new DAOException("3 USDS-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("4 USDS-SQL " + ex.getMessage());
            }
        }
        return contador;
    }

    public boolean validaUsuario(String loginUsuario, String contrasena)
            throws DAOException {
        Connection conexion = null;
        CallableStatement sentencia = null;
        ResultSet resultado = null;
        boolean valido = false;
        try {
            query = "{call SSMA_VALIDA_USUARIO_P('" + loginUsuario.trim() + "','" + contrasena + "')}";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareCall(query);
            sentencia.execute();
            resultado = sentencia.getResultSet();
            valido = resultado.next();
        } catch (SQLException ex) {
            throw new DAOException("1 USDP-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("2 USDP-SQL " + ex.getMessage());
            }
        }
        return valido;
    }

    public boolean cambiarContrasena(String login, String contraActual, String contraNueva)
            throws DAOException {
        Connection conexion = null;
        CallableStatement sentencia = null;
        ResultSet resultado = null;
        boolean cambioCorrecto = false;
        try {
            query = "{call SSMA_CAMBIAR_CONTRASENA_P('" + login.trim() + "','" + contraActual + "','" + contraNueva + "')}";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareCall(query);
            sentencia.execute();
            resultado = sentencia.getResultSet();
            resultado.next();
            cambioCorrecto = resultado.getBoolean(1);
        } catch (SQLException ex) {
            throw new DAOException("3 USDP-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("4 USDP-SQL " + ex.getMessage());
            }
        }
        return cambioCorrecto;
    }

    public String restaurarContrasena(String login)
            throws DAOException {
        Connection conexion = null;
        CallableStatement sentencia = null;
        ResultSet resultado = null;
        String nueva = "";
        try {
            query = "{call SSMA_RESET_CONTRASENA_P('" + login.trim() + "')}";
            conexion = ConexionPool.getInstancia().getConexion();
            sentencia = conexion.prepareCall(query);
            sentencia.execute();
            resultado = sentencia.getResultSet();
            resultado.next();
            nueva = resultado.getString(1);
        } catch (SQLException ex) {
            throw new DAOException("5 USDP-SQL " + ex.getMessage());
        } finally {
            try {
                if (resultado != null) {
                    resultado.close();
                }
                if (sentencia != null) {
                    sentencia.close();
                }
                if (conexion != null) {
                    conexion.close();
                }
            } catch (SQLException ex) {
                throw new DAOException("6 USDP-SQL " + ex.getMessage());
            }
        }
        return nueva;
    }
}
